﻿# coding: utf-8

import weakref

import wx
import wx.lib.colourselect as csel
import wx.lib.scrolledpanel as scrolled

from wxFramework.CustomUI import wxColorPickButton

import ParticleEmitter

class wxPanelPropertyParticleEmitter(scrolled.ScrolledPanel):
    EMIT_PROP_NAME = [
        'CountMin',
        'CountMax',
        'ScatterMin',
        'ScatterMax',
        'LifeMin',
        'LifeMax',
        'SpeedMin',
        'SpeedMax',
        'RotationMin',
        'RotationMax',
        'Color',
        'ParticleSizeMin',
        'ParticleSizeMax',
        'SameWidthHeight',
        'ParticleBlendMode',
        'TextureFrame',
    ]
    
    EMIT_PROP_DICT = {
        'CountMin' : [TD.MIN_EMIT_COUNT, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'CountMax' : [TD.MAX_EMIT_COUNT, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'ScatterMin' : [TD.MIN_SCATTER, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'ScatterMax' : [TD.MAX_SCATTER, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'LifeMin' : [TD.MIN_LIFE, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : abs(int(n))],
        'LifeMax' : [TD.MAX_LIFE, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : abs(int(n))],
        'SpeedMin' : [TD.MIN_SPEED, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'SpeedMax' : [TD.MAX_SPEED, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'RotationMin' : [TD.MIN_ROTATION, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'RotationMax' : [TD.MAX_ROTATION, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : float(n)],
        'Color' : [TD.PARTICLE_COLOR, wxColorPickButton, 0, csel.EVT_COLOURSELECT, lambda n : WXCOLOR_TO_DWORD(n)],
        'ParticleSizeMin' : [TD.MIN_SIZE, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : map(float, n.split(','))],
        'ParticleSizeMax' : [TD.MAX_SIZE, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : map(float, n.split(','))],
        'SameWidthHeight' : [TD.SAME_WIDTH_HEIGHT, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : bool(eval(n))],
        'ParticleBlendMode' : [TD.BLEND_MODE, wx.ComboBox, wx.CB_DROPDOWN|wx.CB_READONLY, wx.EVT_COMBOBOX, lambda n : abs(int(n))],
        'TextureFrame' : [TD.TEXTURE_FRAME, wx.TextCtrl, 0, wx.EVT_KILL_FOCUS, lambda n : abs(int(n))],
    }    
    
    def __init__(self, parent, id):
        scrolled.ScrolledPanel.__init__(self, parent, id)
        
        self._controlDict = {}

        
        sizer = wx.BoxSizer(wx.VERTICAL)
        for key in wxPanelPropertyParticleEmitter.EMIT_PROP_NAME:
            val = wxPanelPropertyParticleEmitter.EMIT_PROP_DICT[key]
            static = wx.StaticText(self, wx.NewId(), val[0])
            control = val[1](self, wx.NewId(), '', style = val[2])
            self._controlDict[key] = control
            control._prop_name = key
            control._prop_type_conv = val[4]
            control.Bind(val[3], self.__OnPropertyChanged)
            sizerItem = wx.BoxSizer(wx.HORIZONTAL)
            sizerItem.Add(static, 0, wx.CENTER, border = 5)
            sizerItem.Add(control, 1, wx.ALL|wx.EXPAND, border = 5)
            sizer.Add(sizerItem, 0, wx.TOP|wx.LEFT, border = 5)     
            
        self.SetSizer(sizer)       
            
        self._controlDict['ParticleBlendMode'].Append(u'SrcAlpha_InvSrcAlpha')
        self._controlDict['ParticleBlendMode'].Append(u'SrcAlpha_One')
        
        self._emitterRef = None
        
        self.Show(False)
        
    def SetEmitter(self, emitter):
        self._emitterRef = weakref.ref(emitter)
        for key in wxPanelPropertyParticleEmitter.EMIT_PROP_NAME:
            control = self._controlDict[key]
            self.__UpdateProperty(control, emitter)       
        
    def __OnPropertyChanged(self, e):
        try:
            emitter = self._emitterRef()
            coreHandle = emitter.GetCoreHandle()
            
        except:
            return
            
        control = e.GetEventObject()
        if type(control) == wx.TextCtrl:
            value = control.GetValue()
        elif type(control) == wxColorPickButton:
            value = e.GetValue()
        elif type(control) == wx.ComboBox:
            value = e.GetSelection()
        else:
            return
            
        prop_name = control._prop_name
        prop_type_conv = control._prop_type_conv

        try:        
            func = ParticleEmitter.__dict__.get('Set%s' % prop_name, None)
            func_param = prop_type_conv(value)
            if type(func_param) == list:
                assert(len(func_param) > 1)
                func(coreHandle, *func_param)
            else:
                func(coreHandle, func_param)
            
        except:
            SHOW_TRACE()
            return
            
    def __UpdateProperty(self, control, emitter):
        coreHandle = emitter.GetCoreHandle()
                    
        prop_type_conv = lambda n : n
        
        if type(control) == wx.TextCtrl:
            set_func = control.SetValue
            prop_type_conv = lambda n : str(n)
        elif type(control) == wxColorPickButton:
            set_func = control.SetValue
            prop_type_conv = lambda n : DWORD_TO_WXCOLOR(n)
        elif type(control) == wx.ComboBox:
            set_func = control.SetSelection
        else:
            return
            
        prop_name = control._prop_name
        try:
            func = ParticleEmitter.__dict__.get('Get%s' % prop_name, None)
            value = func(coreHandle)
            if type(value) == tuple:
                set_func(str(value)[1:-1])
            else:
                set_func(prop_type_conv(value))
            
        except:
            SHOW_TRACE()
            return